package com.jetbrains.kmpapp.di

import com.jetbrains.kmpapp.data.InMemoryMuseumStorage
import com.jetbrains.kmpapp.data.KtorMuseumApi
import com.jetbrains.kmpapp.data.MuseumApi
import com.jetbrains.kmpapp.data.MuseumRepository
import com.jetbrains.kmpapp.data.MuseumStorage
import com.jetbrains.kmpapp.ui.detail.DetailViewModel
import com.jetbrains.kmpapp.ui.list.ListViewModel
import io.ktor.client.HttpClient
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.http.ContentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import org.koin.core.KoinApplication
import org.koin.core.context.startKoin
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.module

object Koin {

    val dataModule = module {
        single {
            val json = Json { ignoreUnknownKeys = true }
            HttpClient {
                install(ContentNegotiation) {
                    // TODO Fix API so it serves application/json
                    json(json, contentType = ContentType.Any)
                }
            }
        }

        single<MuseumApi> { KtorMuseumApi(get()) }
        single<MuseumStorage> { InMemoryMuseumStorage() }
        single {
            MuseumRepository(get(), get()).apply {
                initialize()
            }
        }
    }

    val viewModelModule = module {
        factoryOf(::ListViewModel)
        factoryOf(::DetailViewModel)
    }

    fun start(configuration: KoinApplication.() -> Unit = {}) {
        startKoin {
            modules(
                dataModule,
                viewModelModule,
            )

            configuration()
        }
    }

}